package com.ipartek.formacion.gestformwww.modelo.clases;

import com.ipartek.formacion.gestformwww.modelo.beans.PlantillaSMS;
import com.ipartek.formacion.gestformwww.modelo.beans.SMSEnvio;
import com.ipartek.formacion.gestformwww.modelo.beans.SMSEnviosAlumno;
import com.ipartek.formacion.gestformwww.modelo.beans.SMSEnviosCandidato;
import com.ipartek.formacion.gestformwww.modelo.beans.excepciones.GestorFormacionExcepcion;
import com.ipartek.formacion.gestformwww.modelo.beans.mensatek;
import com.ipartek.formacion.gestformwww.modelo.interfaces.ISMSDAO;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author David y Borja
 */
public class SQLServerSMSDAO implements ISMSDAO {

    private static ResourceBundle rb;

    public SQLServerSMSDAO() {
        rb = ResourceBundle.getBundle("com.ipartek.formacion.gestformwww.controlador.excepciones");
    }

    public SMSEnviosAlumno instanciarSms(ResultSet rs) throws SQLException {

        SMSEnviosAlumno sms = new SMSEnviosAlumno();
        sms.setIdAlumno(rs.getInt("IDAlumno"));
        sms.setSMSMendID(rs.getInt("SMSMenID"));
        sms.setIdCurso(rs.getInt("IDCurso"));
        sms.setIdRespuesta(rs.getInt("IDRespuesta"));
        sms.setFechaHora(rs.getTimestamp("FechaHora"));
        sms.setMovil(rs.getString("Móvil"));
        sms.setMensaje(rs.getString("Mensaje"));

        return sms;
    }

    public SMSEnvio instanciarSmsCandidato(ResultSet rs) throws SQLException {

        SMSEnvio sms = new SMSEnvio();
        sms.setIdCandidato(rs.getInt("IDCandidato"));
        sms.setSmsMenId(rs.getInt("SMSMenID"));
        sms.setIdConvocatoria(rs.getInt("IDConvocatoria"));
        sms.setIdRespuesta(rs.getInt("IDRespuesta"));
        sms.setFechaHora(rs.getTimestamp("FechaHora"));
        sms.setMovil(Integer.parseInt(rs.getString("Móvil")));
        sms.setMensaje(rs.getString("Mensaje"));

        return sms;
    }

    /**
     * Crea una instancia de un objeto plantilla a partir del resultset obtenido de la base de datos
     * @param ResultSet de la basa de datos
     * @return Plantilla de SMS.
     */
    private PlantillaSMS instanciarPlantilla(ResultSet rs) throws SQLException {
        PlantillaSMS plantilla = new PlantillaSMS();

        plantilla.setSMSMenId(rs.getInt("SMSMenId"));
        plantilla.setSMSMenMensaje(rs.getString("SMSMenMensaje"));
        plantilla.setSMSMenObservaciones(rs.getString("SMSMenObservaciones"));
        plantilla.setAceptado(rs.getBoolean("Aceptado"));
        plantilla.setCita(rs.getBoolean("Cita"));
        plantilla.setSMSMenActivo(rs.getBoolean("SMSMenActivo"));
        plantilla.setSMSMenDesc(rs.getString("SMSMenDesc"));

        return plantilla;
    }

    public ArrayList<SMSEnviosAlumno> listarSMS(Integer idCurso, Integer idAlumno) throws GestorFormacionExcepcion {

        ArrayList<SMSEnviosAlumno> listaSms = new ArrayList<SMSEnviosAlumno>();
        SMSEnviosAlumno sms = new SMSEnviosAlumno();
        Connection conexion = null;
        String sql = null;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            sql = "SELECT IDAlumno, SMSMenID, IDCurso, IDRespuesta, FechaHora, Móvil, Mensaje FROM SMSEnvios_Alumnos WHERE IDCurso=" + idCurso + " AND IDAlumno=" + idAlumno + " ORDER BY FechaHora DESC";
            PreparedStatement stmt = conexion.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                sms = instanciarSms(rs);
                listaSms.add(sms);
            }
            stmt.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }
        listaSms = obtenerEstado(listaSms);

        return listaSms;

    }

    public ArrayList<SMSEnviosAlumno> obtenerEstado(ArrayList<SMSEnviosAlumno> listasms) throws GestorFormacionExcepcion {

        String estado = null;
        Connection conexion = null;
        String sql = null;
        SMSEnviosAlumno sms = new SMSEnviosAlumno();

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            for (int i = 0; i < listasms.size(); i++) {
                sql = "SELECT  SMSResObservaciones FROM  SMSRespuesta WHERE SMSResId=" + listasms.get(i).getIdRespuesta();
                PreparedStatement stmt = conexion.prepareStatement(sql);
                ResultSet rs = stmt.executeQuery();
                while (rs.next()) {
                    //sms = instanciarSms(listasms.get(i));
                    //sms.setObservaciones(rs.getString("SMSResObservaciones"));
                    listasms.get(i).setObservaciones(rs.getString("SMSResObservaciones"));
                    //listasms.add(sms);
                }
                stmt.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }

        return listasms;
    }

    private ArrayList<SMSEnvio> obtenerEstadoCandidato(ArrayList<SMSEnvio> listasms) throws GestorFormacionExcepcion {

        Connection conexion = null;
        String sql = null;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            for (int i = 0; i < listasms.size(); i++) {
                sql = "SELECT  SMSResObservaciones FROM  SMSRespuesta WHERE SMSResId=" + listasms.get(i).getIdRespuesta();
                PreparedStatement stmt = conexion.prepareStatement(sql);
                ResultSet rs = stmt.executeQuery();
                while (rs.next()) {
                    listasms.get(i).setObservaciones(rs.getString("SMSResObservaciones"));
                }
                stmt.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }

        return listasms;
    }
    /*   public ArrayList<Plantilla> listarPlantillasSMS(){

    plantilla.setSMSMenId(rs.getInt("SMSMenId"));
    plantilla.setSMSMenMensaje(rs.getString("SMSMenMensaje"));
    plantilla.setSMSMenObservaciones(rs.getString("SMSMenObservaciones"));
    plantilla.setAceptado(rs.getBoolean("Aceptado"));
    plantilla.setCita(rs.getBoolean("Cita"));
    plantilla.setSMSMenActivo(rs.getBoolean("SMSMenActivo"));
    plantilla.setSMSMenDesc(rs.getString("SMSMenDesc"));

    return plantilla;
    }

    /**
     * Lista de la basa de datos las plantilla de SMS predefinidas
     * @return Array con las plantillas predefinidas de la base de datos
     */

    public ArrayList<PlantillaSMS> listarPlantillasSMS() throws GestorFormacionExcepcion {
        ArrayList<PlantillaSMS> plantillas = new ArrayList<PlantillaSMS>();
        Connection conexion = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            stmt = conexion.prepareStatement("SELECT * FROM SMSMensajes");
            rs = stmt.executeQuery();

            while (rs.next()) {
                plantillas.add(instanciarPlantilla(rs));
            }

            stmt.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }
        return plantillas;
    }

    /**
     * Guarda el sms enviado en la base de datos.
     * @param envio
     * @throws GestorFormacionExcepcion
     */
    private void guardarSMS(SMSEnviosAlumno envio) throws GestorFormacionExcepcion {
        Connection con = null;

        try {
            con = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            PreparedStatement sql = con.prepareStatement("INSERT INTO SMSEnvios_Alumnos(IDAlumno,IDCurso,IDRespuesta,FechaHora,Móvil,Mensaje,SMSMenID) VALUES(?,?,?,?,?,?,?)");

            sql.setInt(1, envio.getIdAlumno());
            sql.setInt(2, envio.getIdCurso());
            sql.setInt(3, envio.getIdRespuesta());
            sql.setTimestamp(4, envio.getFechaHora());
            sql.setString(5, envio.getMovil());
            sql.setString(6, envio.getMensaje());
            sql.setInt(7, envio.getSMSMendID());//Para que no casque.

            sql.executeUpdate();
            sql.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));

        } finally {
            SQLServerDAOFactory.desconecta(con);
        }
    }

    /**
     * Actualiza el numero de telefono para un alumno
     * @param id
     * @param numero
     * @throws GestorFormacionExcepcion
     */
    private void actualizarNumero(int id, String numero) throws GestorFormacionExcepcion {
        Connection con = null;

        try {
            con = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }
        try {
            PreparedStatement sql = con.prepareStatement("UPDATE Alumno SET AluTlf1=? WHERE AluId=?");
            sql.setString(1, numero);
            sql.setInt(2, id);
            sql.executeUpdate();
            sql.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));

        } finally {
            SQLServerDAOFactory.desconecta(con);
        }
    }

    /**
     * Envia un sms y actualiza la Base de Datos.
     * @param envio
     * @throws GestorFormacionExcepcion
     */
    public void enviarSMS(SMSEnviosAlumno envio, ResourceBundle recurso) throws GestorFormacionExcepcion {
        mensatek mensatek = new mensatek();
        String resultado;

        if (envio.getMovil().isEmpty()) {
            envio.setObservaciones("No tiene telefono");
            return;
        }

        resultado = mensatek.enviar(recurso.getString("usuario-sms"), recurso.getString("pass-sms"), "34" + envio.getMovil(), envio.getMensaje(), "remite-sms", envio.getFechaHora().toString(), Integer.parseInt(recurso.getString("flash-sms")), Integer.parseInt(recurso.getString("report-sms")), Integer.parseInt(recurso.getString("credito-sms")));
        switch (Integer.parseInt(mensatek.formatearRespuestaEnvioSMS(resultado))) {
            case 1:
                //Error de autenticación
                envio.setIdRespuesta(1);
                envio.setObservaciones("Error de autenticación");
                break;
            case 2:
                //no hay créditos suficientes.
                envio.setIdRespuesta(2);
                envio.setObservaciones("No hay créditos suficientes");
                break;
            case 3:
                // Error en los datos de la llamada
                envio.setIdRespuesta(3);
                envio.setObservaciones("Error en los datos de la llamada");
                break;
            case 5:
                //Enviado bien
                envio.setIdRespuesta(5);
                envio.setObservaciones("Enviado correctamente");

                //Si el numero es nuevo, actualizar el alumno
                if (envio.getMovilNuevo()) {
                    actualizarNumero(envio.getIdAlumno(), envio.getMovil());
                }
                break;
            default:
                envio.setIdRespuesta(6);
                envio.setObservaciones("Error interno");
                break;
        }
        guardarSMS(envio);
    }

    public boolean GuardarResSmSCandidato(ArrayList<SMSEnvio> alSmsEnvio) throws GestorFormacionExcepcion {
        boolean res = false;
        Connection conexion = null;
        SentenciaNula stmt = null;
        ResultSet rs = null;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            for (SMSEnvio sms : alSmsEnvio) {
                stmt = new SentenciaNula(conexion, "INSERT INTO SMSEnvios (IdCandidato,SMSMenId,IDConvocatoria,IDRespuesta,FechaHora,Móvil,Mensaje) VALUES(?,?,?,?,?,?,?)");
                stmt.setInt(1, sms.getIdCandidato());
                stmt.setInt(2, sms.getSmsMenId());
                stmt.setInt(3, sms.getIdConvocatoria());
                stmt.setInt(4, sms.getIdRespuesta());
                stmt.setTimestamp(5, sms.getFechaHora());
                stmt.setInt(6, sms.getMovil());
                stmt.setString(7, sms.getMensaje());
                stmt.executeUpdate();
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }

        return res;
    }

    public PlantillaSMS buscarPlantilla(int idPlantilla) throws GestorFormacionExcepcion {
        PlantillaSMS plantilla = new PlantillaSMS();
        Connection conexion = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            stmt = conexion.prepareStatement("SELECT * FROM SMSMensajes WHERE SMSMenId=" + idPlantilla);
            rs = stmt.executeQuery();

            while (rs.next()) {
                plantilla = instanciarPlantilla(rs);
            }

            stmt.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }
        return plantilla;
    }

    public String obtenerDescripcionRespuesta(int idRes) throws GestorFormacionExcepcion {

        String estado = null;
        Connection conexion = null;
        String sql = null;
        String res = "";

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {

            sql = "SELECT  SMSResObservaciones FROM  SMSRespuesta WHERE SMSResId=" + idRes;
            PreparedStatement stmt = conexion.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                res = rs.getString("SMSResObservaciones");
                stmt.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }

        return res;
    }

    public ArrayList<SMSEnvio> listarSMSCandidato(Integer idCon, Integer idCan) throws GestorFormacionExcepcion {

        ArrayList<SMSEnvio> listaSms = new ArrayList<SMSEnvio>();
        SMSEnvio sms = new SMSEnvio();
        Connection conexion = null;
        String sql = null;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            sql = "SELECT IDCandidato, SMSMenID, IDConvocatoria, IDRespuesta, FechaHora, Móvil, Mensaje FROM SMSEnvios WHERE IDConvocatoria=" + idCon + " AND IDCandidato=" + idCan + "ORDER BY FechaHora DESC";
            PreparedStatement stmt = conexion.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                sms = instanciarSmsCandidato(rs);
                listaSms.add(sms);
            }
            stmt.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }

        listaSms = obtenerEstadoCandidato(listaSms);

        return listaSms;

    }

    public void enviarSMSCandidato(SMSEnviosCandidato envio, ResourceBundle recurso) {
        mensatek mensatek = new mensatek();
        String resultado;

        if (envio.getMovil().isEmpty()) {
            envio.setObservaciones("No tiene telefono");
            return;
        }

        resultado = mensatek.enviar(recurso.getString("usuario-sms"), recurso.getString("pass-sms"), "34" + envio.getMovil(), envio.getMensaje(), "remite-sms", envio.getFechaHora().toString(), Integer.parseInt(recurso.getString("flash-sms")), Integer.parseInt(recurso.getString("report-sms")), Integer.parseInt(recurso.getString("credito-sms")));
        switch (Integer.parseInt(mensatek.formatearRespuestaEnvioSMS(resultado))) {
            case 1:
                //Error de autenticación
                envio.setIdRespuesta(1);
                envio.setObservaciones("Error de autenticación");
                break;
            case 2:
                //no hay créditos suficientes.
                envio.setIdRespuesta(2);
                envio.setObservaciones("No hay créditos suficientes");
                break;
            case 3:
                // Error en los datos de la llamada
                envio.setIdRespuesta(3);
                envio.setObservaciones("Error en los datos de la llamada");
                break;
            case 5:
                //Enviado bien
                envio.setIdRespuesta(5);
                envio.setObservaciones("Enviado correctamente");

                //Si el numero es nuevo, actualizar el alumno
                if (envio.getMovilNuevo()) {
            try {
                actualizarNumero(envio.getIdCandidato(), envio.getMovil());
            } catch (GestorFormacionExcepcion ex) {
                Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
                }
                break;
            default:
                envio.setIdRespuesta(6);
                envio.setObservaciones("Error interno");
                break;
        }
        try {
            guardarSMSCandidato(envio);
        } catch (GestorFormacionExcepcion ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
     /**
     * Guarda el sms enviado en la base de datos.
     * @param envio
     * @throws GestorFormacionExcepcion
     */
    private void guardarSMSCandidato(SMSEnviosCandidato envio) throws GestorFormacionExcepcion {
        Connection con = null;

        try {
            con = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            PreparedStatement sql = con.prepareStatement("INSERT INTO SMSEnvios (IDCandidato, SMSMenID, IDConvocatoria,IDRespuesta, FechaHora, Móvil, Mensaje,) VALUES(?,?,?,?,?,?,?)");

            sql.setInt(1, envio.getIdCandidato());
            sql.setInt(2, envio.getSMSMenID());
            sql.setInt(3, envio.getIdConvocatoria());
            sql.setInt(4, envio.getIdRespuesta());
            sql.setTimestamp(5, envio.getFechaHora());
            sql.setString(6, envio.getMovil());
            sql.setString(7, envio.getMensaje());

            sql.executeUpdate();
            sql.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerSMSDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));

        } finally {
            SQLServerDAOFactory.desconecta(con);
        }
    }
}
